package cn.flying.cloud.oauth.server.configuration.handler;

import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson2.JSON;

import cn.flying.cloud.base.common.constants.Constants;
import cn.flying.cloud.base.common.enums.RtCodeEnum;
import cn.flying.cloud.base.common.exception.BizException;
import cn.flying.cloud.base.common.utils.Ft;
import cn.flying.cloud.base.common.vo.Rt;
import cn.flying.cloud.base.redis.service.RedisService;
import cn.flying.cloud.oauth.server.configuration.details.UserDetail;
import cn.flying.cloud.oauth.server.vo.LoginResult;

/**
 * @description: 登录认证成功处理类  这里采用继承，可以继承默认的处理规则，这里可以根据不同判断实现不同的返回处理（如果是Oauth认证，不会走这里）
 * @author: admin
 * @date: 2023年05月25日 12:37
 * @version: 1.0
 */
@Component
public class CustomAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Resource
    private RedisService redisService;

//    @Resource
//    private JwtUtil jwtUtil;

    /**
     * Called when a user has been successfully authenticated.
     *
     * @param request        the request which caused the successful authentication
     * @param response       the response
     * @param authentication the <tt>Authentication</tt> object which was created during
     */
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        //获取当登录用户信息
        UserDetail userDetail = (UserDetail) authentication.getPrincipal();
        if (Objects.isNull(userDetail)) {
            throw new BizException("没有获取到当前登录信息");
        }

        String accessToken;
        String refreshToken;
        String jwtId = UUID.randomUUID().toString();
        long expire = 60 * 60 * 1000L;
        try {
            accessToken = Ft.Jwt.createToken(userDetail.getUsername(), userDetail.getUsername(), jwtId, expire);
            refreshToken = Ft.Jwt.createToken(userDetail.getUsername(), userDetail.getUsername(), jwtId, expire * 10);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        LoginResult result = new LoginResult();
        result.setTokenType("bearer");
        result.setAccessToken(accessToken);
        result.setExpiresIn(Objects.requireNonNull(Ft.Jwt.getExpiredDate(accessToken)).getTime());
        result.setRefreshToken(refreshToken);
        result.setJti(jwtId);
        Map<String, Object> userInfo = new HashMap<>();
        userInfo.put("tenantId", userDetail.getTenantId());
        userInfo.put("avatar", userDetail.getAvatar());
        userInfo.put("userName", userDetail.getUsername());
        userInfo.put("userId", userDetail.getUserId());
        result.setUserInfo(userInfo);

        //将token放入缓存
        String tokenKey = Constants.ACCESS_TOKEN + ":" + jwtId;
        redisService.set(tokenKey, JSON.toJSONString(userDetail), expire);

        response.setContentType("application/json;charset=utf-8");
        PrintWriter out = response.getWriter();
        //登录成功返回用户信息（accessToken）
        out.write(JSON.toJSONString(Rt.result(RtCodeEnum.R_SUCCESS, result)));
        out.flush();
        out.close();
    }
}
